﻿#region using
using System;
using System.IO;
using System.Text;
#endregion using

namespace MpSoft.Collections.Helpers
{
    public static class ArrayExt
    {
        public static int FindArrIndex<T>(T[] source,T[] toFind)
        {
            return FindArrIndex<T>(source,toFind,0,-1);
        }

        public static int FindArrIndex<T>(T[] source,T[] toFind,int startIndex)
        {
            return FindArrIndex<T>(source,toFind,startIndex,-1);
        }

        public static int FindArrIndex<T>(T[] source,T[] toFind,int startIndex,int count)
        {
            if (source==null)
                throw new ArgumentNullException("source");
            if (toFind==null)
                throw new ArgumentNullException("toFind");
            int len=source.Length;
            if (len==0)
                return -1;
            if (toFind.Length==0)
                throw new ArgumentException("toFind");
            if (count==-1)
                count=len;

            T firstEl=toFind[0];
            int pos=Array.IndexOf(source,firstEl,startIndex,count-startIndex);
            while (pos!=-1)
            {
                bool found=true;
                int a=0;
                foreach (T el in toFind)
                    if (!object.Equals(source[pos+(a++)],el))
                    {
                        found=false;
                        break;
                    }
                if (found)
                    return pos;

                pos=pos+1;
                pos=Array.IndexOf(source,firstEl,pos,count-pos);
            }
            return -1;
        }

        public static bool BinaryEquals<T>(T[] dataX,int indexX,T[] dataY,int indexY,int size)
        {
            if (dataX.Length<indexX+size)
                throw new IndexOutOfRangeException();
            if (dataY.Length<indexY+size)
                throw new IndexOutOfRangeException();
            for (int a=0;a<size;a++)
                if (!object.Equals(dataX[a+indexX],dataY[a+indexY]))
                    return false;
            return true;
        }
    }
}

namespace MpSoft.IO
{
    using MpSoft.Collections.Helpers;

    public class BytesReader
    {
        byte[] _bytes;
        int _position;
        public BytesReader(byte[] bytes)
        {
            _bytes=bytes;
        }

        static byte[] _newLine=new byte[]{13,10};
        public string ReadLine(Encoding encoding)
        {
            int newPos=ArrayExt.FindArrIndex(_bytes,_newLine,_position);
            string result=encoding.GetString(_bytes,_position,newPos-_position);
            _position=newPos+2;
            return result;
        }

        public string ReadToEnd(Encoding encoding)
        {
            int newPos=_bytes.Length;
            string result=encoding.GetString(_bytes,_position,newPos-_position);
            _position=newPos;
            return result;
        }

        public string ReadToBreak(Encoding encoding,byte[] partsDelimiter)
        {
            int newPos=ArrayExt.FindArrIndex(_bytes,partsDelimiter,_position);
            string result=encoding.GetString(_bytes,_position,newPos-_position);
            _position=newPos+partsDelimiter.Length;
            return result;
        }

        public byte[] ReadToBreak(byte[] partsDelimiter)
        {
            int newPos=ArrayExt.FindArrIndex(_bytes,partsDelimiter,_position);
            int len=newPos-_position;
            byte[] result=new byte[len];
            Array.Copy(_bytes,_position,result,0,len);
            _position=newPos+partsDelimiter.Length;
            return result;
        }

        public int Position { get { return _position; } set { _position = value; } }
        public int Length { get { return _bytes.Length; } }
    }
}
